#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <linux/fb.h>

#include "bmp.h"
#include "lcd.h"


void load_bmp(const char *bmpfile, struct img_info *bmpinfo)
{
    FILE *fp = fopen(bmpfile, "r");

    struct bitmap_header head;
    struct bitmap_info   info;
    struct rgb_quad      quad;
    fread(&head, sizeof(head), 1, fp);
    fread(&info, sizeof(info), 1, fp);
    if(info.compression)
        fread(&quad, sizeof(quad), 1, fp);

    bmpinfo->width = info.width;
    bmpinfo->height= info.height;
    bmpinfo->bpp   = info.bit_count;
    printf("图片尺寸：%d × %d （色深%d比特）\n", bmpinfo->width,
                                                bmpinfo->height,
                                                bmpinfo->bpp);

    bmpinfo->size = info.width*info.height*info.bit_count/8;
    bmpinfo->rgb = calloc(1, bmpinfo->size);

    // 加载RGB数据
    int n, total=0, rgbsize=bmpinfo->size;
    while(rgbsize > 0)
    {
        n = fread(bmpinfo->rgb+total, 1, rgbsize, fp); // n就是实际读到的字节数

        rgbsize -= n;
        total   += n;
    }
    printf("total: %d\n", total);
    
    fclose(fp);
}

void show_img(struct lcd_info *lcdinfo, const char *filename)
{
    // 加载图片信息
    struct img_info *imginfo = calloc(1, sizeof(struct img_info));
    load_bmp(filename, imginfo);

    // 清屏
    clean_screen(lcdinfo);

    // 居中指针
    int x, y;
    x = (lcdinfo->width  - imginfo->width) /2;
    y = (lcdinfo->height - imginfo->height)/2;
    char *tmp = lcdinfo->fb_mem + (800*(y-1) + x)*4;

    int wlcd = lcdinfo->width  - x;
    int hlcd = lcdinfo->height - y;

    // 计算无效字节
    int linesize = imginfo->width*imginfo->bpp/8;
    int pad = (4-linesize%4) % 4; // 0 ~ 3

    // 取最底一行的指针
    char *rgb = imginfo->rgb + (linesize+pad)*(imginfo->height-1);

    // 4-> 按照img的特性将RGB显示出来
    int w, h;
    for(w=0, h=0; h<imginfo->height && h<wlcd; h++)
    {
        unsigned lcd_offset = h * lcdinfo->width*4;
        
        // 显示一行
        for(w=0; w<imginfo->width && w<wlcd; w++)
            memcpy(tmp + w*4 + lcd_offset, rgb + w*3 , 3);

        rgb -= (linesize + pad);
    }
}

void release_bmp(struct img_info *bmpinfo)
{
    // ..
}
